package com.example.gobang_system.service.impl;

import com.example.gobang_system.common.errorcode.ServiceErrorCodeConstants;
import com.example.gobang_system.common.exception.ServiceException;
import com.example.gobang_system.common.pojo.UserInfo;
import com.example.gobang_system.common.util.SecurityUtil;
import com.example.gobang_system.controller.param.UserLoginParam;
import com.example.gobang_system.controller.param.UserRegisterParam;
import com.example.gobang_system.dao.dataobject.UserDO;
import com.example.gobang_system.dao.mapper.UserMapper;
import com.example.gobang_system.service.UserService;
import com.example.gobang_system.service.dto.UserInfoDTO;
import com.example.gobang_system.service.dto.UserLoginDTO;
import com.example.gobang_system.service.dto.UserRegisterResultDTO;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.regex.Pattern;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    /**
     * 获取用户信息
     * @param session
     * @return
     */
    @Override
    public UserInfoDTO getUserInfo(HttpSession session) {
        // 参数校验
        if (null == session) {
            return null;
        }
        // 从 session 中获取用户信息
        UserInfo userInfo = (UserInfo) session.getAttribute(USER_INFO);
        if (null == userInfo) {
            return null;
        }
        // 从数据库中获取 用户信息
        UserDO userDO = userMapper.selectByUserId(userInfo.getUserId());
        // 构造响应并返回
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setUserId(userDO.getId());
        userInfoDTO.setUserName(userDO.getUserName());
        userInfoDTO.setScore(userDO.getScore());
        userInfoDTO.setTotalCount(userDO.getTotalCount());
        userInfoDTO.setWinCount(userDO.getWinCount());
        return userInfoDTO;
    }

    /**
     * 用户登录
     * @param param
     * @return
     */
    @Override
    public UserLoginDTO login(UserLoginParam param, HttpSession session) {
        // 参数校验
        checkPassword(param.getPassword());
        // 获取用户信息
        UserDO userDO = userMapper.selectByUserName(param.getName());
        // 用户信息是否存在
        if (null == userDO) {
            throw new ServiceException(ServiceErrorCodeConstants.USER_INFO_IS_EMPTY);
        }
        // 校验密码是否正确
        if (!SecurityUtil.verifyPassword(param.getPassword(),
                userDO.getPassword())) {
            throw new ServiceException(ServiceErrorCodeConstants.PASSWORD_CHECK_ERROR);
        }

        // 将用户信息 存储到 session 中
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userDO.getId());
        userInfo.setUserName(userDO.getUserName());
        userInfo.setScore(userDO.getScore());
        userInfo.setTotalCount(userDO.getTotalCount());
        userInfo.setWinCount(userDO.getWinCount());
        session.setAttribute(USER_INFO, userInfo);

        // 构造响应并返回
        UserLoginDTO userLoginDTO = new UserLoginDTO();
        userLoginDTO.setUserId(userDO.getId());
        return userLoginDTO;
    }

    /**
     * 用户注册
     * @param param
     * @return
     */
    @Override
    public UserRegisterResultDTO register(UserRegisterParam param) {
        // 参数校验
        if (!checkPassword(param.getPassword())) {
            throw new ServiceException(ServiceErrorCodeConstants.PASSWORD_CHECK_ERROR);
        }
        // 数据入库
        UserDO userDO = new UserDO();
        userDO.setUserName(param.getName());
        userDO.setPassword(SecurityUtil.encipherPassword(param.getPassword()));
        userMapper.insert(userDO);
        // 构造响应并返回
        UserRegisterResultDTO registerResultDTO = new UserRegisterResultDTO();
        registerResultDTO.setUserId(userDO.getId());
        return registerResultDTO;
    }

    /**
     * 密码校验
     * @param password
     * @return
     */
    private boolean checkPassword(String password) {
        if (!StringUtils.hasText(password)) {
            return false;
        }
        // 使用正则表达式校验密码长度为 6 - 12 位(不限制字符类型)
        String regex = "^.{6,12}$";
        return Pattern.matches(regex, password);
    }
}
